package main

import (
	"bytes"
	"fmt"
	"math/rand"
	"strings"
	"testing"
)

const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

// 使用fmt.sprinf拼接
func Sprintf(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return fmt.Sprintf("%s", b)
}

// 使用+拼接
func StrAddJoin(n int) string {
	b := make([]byte, n)
	temp := ""
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
		temp += string(b[i])
	}
	return temp
}

// 使用strings.builder拼接
func Builder(n int) string {
	str := strings.Builder{}
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	str.WriteString(string(b))
	return str.String()
}

// 使用bytes.buffer拼接
func Bytes(n int) string {
	str := bytes.Buffer{}
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	str.WriteString(string(b))
	return str.String()
}

// 使用[]byte拼接
func SliceByte(n int) string {
	b := make([]byte, n)
	for i := range b {
		b[i] = letterBytes[rand.Intn(len(letterBytes))]
	}
	return string(b)
}

// 测试函数
func benchmarkSprintf(i int, b *testing.B) {
	for n := 0; n < b.N; n++ {
		Sprintf(i)
	}
}

func benchmarkStrAddJoin(i int, b *testing.B) {
	for n := 0; n < b.N; n++ {
		StrAddJoin(i)
	}
}

func benchmarkBuilder(i int, b *testing.B) {
	for n := 0; n < b.N; n++ {
		Builder(i)
	}
}

func benchmarkBytes(i int, b *testing.B) {
	for n := 0; n < b.N; n++ {
		Bytes(i)
	}
}

func benchmarkSliceByte(i int, b *testing.B) {
	for n := 0; n < b.N; n++ {
		SliceByte(i)
	}
}

// 测试
func BenchmarkSprintf(b *testing.B) { benchmarkSprintf(1000, b) }

func BenchmarkStrAddJoin(b *testing.B) { benchmarkStrAddJoin(1000, b) }

func BenchmarkBuilder(b *testing.B) { benchmarkBuilder(1000, b) }

func BenchmarkBytes(b *testing.B) { benchmarkBytes(1000, b) }

func BenchmarkSliceByte(b *testing.B) { benchmarkSliceByte(1000, b) }

/*
测试结果
[19:53:05 root@go test]#go test -bench=. -benchmem -run=none
goos: linux
goarch: amd64
pkg: test
cpu: AMD Ryzen 7 4800H with Radeon Graphics         
BenchmarkSprintf-4                 48448             24797 ns/op            2072 B/op          3 allocs/op
BenchmarkStrAddJoin-4               4638            257828 ns/op          535314 B/op       2000 allocs/op
BenchmarkBuilder-4                 47493             25222 ns/op            3072 B/op          3 allocs/op
BenchmarkBytes-4                   46303             25667 ns/op            4096 B/op          4 allocs/op
BenchmarkSliceByte-4               48552             24349 ns/op            2048 B/op          2 allocs/op
PASS
ok      test    7.039s
*/